package org.javahispano.javacup.tacticas_aceptadas.lechuck.myTactics;

import org.javahispano.javacup.modelo.*;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;

public class TacticaLechuck implements Tactica {

    TacticaDetalleLechuck detalle = new TacticaDetalleLechuck();

    Posicion alineacion1[]=new Posicion[]{
            new Posicion(-0.23776223776223776,-48.93665158371041),
            new Posicion(-16.643356643356643,-23.28054298642534),
            new Posicion(11.174825174825173,-23.518099547511312),
            new Posicion(-0.951048951048951,-28.98190045248869),
            new Posicion(11.412587412587413,-8.789592760180994),
            new Posicion(-12.363636363636363,-10.214932126696834),
            new Posicion(20.20979020979021,9.739819004524888),
            new Posicion(-21.3986013986014,9.97737556561086),
            new Posicion(-0.4755244755244755,23.28054298642534),
            new Posicion(-11.65034965034965,40.859728506787334),
            new Posicion(10.461538461538462,37.29638009049774)
        };

        Posicion alineacion2[]=new Posicion[]{
            new Posicion(0.23776223776223776,-49.886877828054295),
            new Posicion(-12.363636363636363,-27.794117647058822),
            new Posicion(11.888111888111888,-28.031674208144796),
            new Posicion(-0.951048951048951,-31.59502262443439),
            new Posicion(2.377622377622378,-20.192307692307693),
            new Posicion(-6.895104895104895,-11.165158371040723),
            new Posicion(19.020979020979023,-10.927601809954751),
            new Posicion(-22.11188811188811,-11.165158371040723),
            new Posicion(-0.7132867132867133,5.226244343891403),
            new Posicion(-12.363636363636363,13.778280542986426),
            new Posicion(9.510489510489512,13.778280542986426)
        };

        Posicion alineacion3[]=new Posicion[]{
            new Posicion(0.0,-51.549773755656105),
            new Posicion(-9.986013986013985,-36.58371040723982),
            new Posicion(10.937062937062937,-37.77149321266968),
            new Posicion(-0.951048951048951,-37.53393665158371),
            new Posicion(4.041958041958042,-24.705882352941178),
            new Posicion(-7.846153846153847,-19.479638009049776),
            new Posicion(22.58741258741259,-29.93212669683258),
            new Posicion(-21.874125874125873,-29.457013574660635),
            new Posicion(3.3286713286713288,-3.3257918552036196),
            new Posicion(-8.321678321678322,9.027149321266968),
            new Posicion(16.167832167832167,-11.877828054298643)
        };

        Posicion alineacion4[]=new Posicion[]{
            new Posicion(0.2595419847328244,-50.41044776119403),
            new Posicion(-11.174825174825173,-32.782805429864254),
            new Posicion(13.79020979020979,-31.357466063348415),
            new Posicion(0.951048951048951,-29.694570135746606),
            new Posicion(-4.041958041958042,-11.64027149321267),
            new Posicion(-17.832167832167833,-16.391402714932127),
            new Posicion(17.356643356643357,-15.91628959276018),
            new Posicion(-22.349650349650346,-2.3755656108597285),
            new Posicion(7.846153846153847,-8.076923076923077),
            new Posicion(0.4755244755244755,0.0),
            new Posicion(23.776223776223777,-1.6628959276018098)
        };

        Posicion alineacion5[]=new Posicion[]{
            new Posicion(0.2595419847328244,-50.41044776119403),
            new Posicion(-11.16030534351145,-35.78358208955224),
            new Posicion(12.717557251908397,-35.26119402985075),
            new Posicion(-0.4755244755244755,-30.16968325791855),
            new Posicion(8.55944055944056,-17.34162895927602),
            new Posicion(-10.937062937062937,-17.57918552036199),
            new Posicion(23.776223776223777,-10.927601809954751),
            new Posicion(-22.825174825174827,-11.165158371040723),
            new Posicion(-0.23776223776223776,-9.97737556561086),
            new Posicion(-9.986013986013985,-3.800904977375566),
            new Posicion(9.034965034965035,-5.463800904977376)
        };

    

    public Posicion[] getPosicionSaca(SituacionPartido sp) {
    	return alineacion4;
    }

    public Posicion[] getPosicionRecive(SituacionPartido sp) {
    	return alineacion5;
    }

    public TacticaDetalle getDetalle() {
        return detalle;
    }
    
    enum BallState{
    	BALL_NO_STATE,
    	BALL_IS_OUT_ATTACK,
    	BALL_IS_OUT_DEFEND,
    	BALL_IS_MINE,
    	BALL_IS_RIVAL,    	
    };
    
    static BallState bState = BallState.BALL_NO_STATE;
    
    Random rand = new Random();
    LinkedList<Comando> comandos = new LinkedList<Comando>();
    
	static double FACTOR_DISMINUCION_VEL = (Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE + 
									 Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO)/2;
	
	//static SituacionPartido previousSP;
	
	Posicion previousBallPos = new Posicion(0,0);

	public List<Comando> ejecutar(SituacionPartido sp) {
        //vacia la lista de comandos
        comandos.clear();
              
        bState = GetBallState(sp);        
        
        switch(bState){
        	case BALL_NO_STATE:
        	{
        		//What should we do here?
        		_ChaseTheBall(sp);
        	}
        	break;
	    	case BALL_IS_OUT_DEFEND:
	    	{
	    		_recoverDefensivePosition(sp);
	    		_markRivals(sp);
	    		_ChaseTheBall(sp);	    		
	    	}
	    	break;
	    	case BALL_IS_OUT_ATTACK:
	    	{
	    		_recoverAttackPosition(sp);
	    		if(sp.puedenRematar().length>0) _kickOffToAFreePlayer(sp);
	    		else _ChaseTheBall(sp);
	    	}
	    	break;
	    	case BALL_IS_MINE:
	    	{
	    		_recoverAttackPosition(sp);
	    		//The ball owner pass the ball, continues with the ball or dribbles the rivals
	    		if(sp.puedenRematar().length>0) _dribblingAction(sp);
	    		else _ChaseTheBall(sp);
	    		//If pass is made, the catcher goes to the proper position
	    		//forward footballers get a better position (not marked positions).
	    		if(sp.balon().getY() < 0){
		    		_goalKeeper(sp);
	    		}
	    	}
	    	break;
	    	case BALL_IS_RIVAL:
	    	{
	    		_recoverDefensivePosition(sp);
	    		_markRivals(sp);	    		
	    		_ChaseTheBall(sp);
	    		_goalKeeper(sp);

	    		// If there're dangerous forward rivals, the nearest players mark them 
	    	} 
	    	break;
        }
        
        previousBallPos = sp.balon();
        
        //retorna la lista de comandos.
        return comandos;
    }
	
	private BallState GetBallState(SituacionPartido sp)
	{
		BallState state = BallState.BALL_NO_STATE;
        if(sp.sacaRival()){
        	state = BallState.BALL_IS_OUT_DEFEND;        	
        }
        else if(sp.saco()){
        	state = BallState.BALL_IS_OUT_ATTACK;        	
        }
        else if(sp.puedenRematar().length > 0){
        	state = BallState.BALL_IS_MINE;
        }
        else if(sp.puedenRematarRival().length > 0){
        	state = BallState.BALL_IS_RIVAL;      	
        }
        else{ //Keep the previous state except after out states
        	if(bState == BallState.BALL_IS_OUT_DEFEND){
        		state = BallState.BALL_IS_RIVAL;
        	}else if(bState == BallState.BALL_IS_OUT_ATTACK){
        		state = BallState.BALL_IS_MINE;
        	}else{
        		state = bState;
        	}        	
        }
        
        return state;		
	}
    
	private void _goalKeeper( SituacionPartido sp ){
		double distance = sp.misJugadores()[0].distancia(_getBallPositionInNIterations(sp, 1)); 
		int rival = sp.balon().indiceMasCercano(sp.rivales());
		double distanceRival = sp.rivales()[rival].distancia(_getBallPositionInNIterations(sp, 1));
		Posicion pFinal = sp.misJugadores()[0];//Constantes.centroArcoInf;
		double speed = previousBallPos.distancia(sp.balon());
		boolean goalDirection = false;
		
        Posicion a = Constantes.centroArcoInf;
        double ang = sp.balon().angulo(a) + Math.PI;               
		
		Posicion pFondo = Posicion.Interseccion(sp.balon(), previousBallPos, Constantes.posteDerArcoInf, Constantes.posteIzqArcoInf);

		if( sp.balon().getX() < 0 && (pFondo.getX() > Constantes.posteIzqArcoInf.getX()) &&
			(pFinal.getX() < Constantes.posteDerArcoInf.getX()) ){
			goalDirection = true;
		}	
		
		if( distance < 8 && distance < distanceRival && sp.alturaBalon() < Constantes.ALTURA_CONTROL_BALON){//(!goalDirection || speed <= 0.2)){
			pFinal = _getBallPositionInNIterations(sp, 1);
		}
		else if(ang > 3*Math.PI/4 && distance > 3){
			pFinal = Constantes.centroArcoInf.moverPosicion( -3.3, 1.8, 5);
		}
		else if(ang < Math.PI/4  && distance > 3){
			pFinal = Constantes.centroArcoInf.moverPosicion( 3.3, 1.8, 5) ;		
		}		
		else if ( goalDirection && ((distance < 30 && goalDirection && speed > 1.8 )
				|| (distance < 11 && distanceRival>4 && speed > 1.0)) ){
			pFinal = pFondo.moverPosicion(0, 2, 0.2 + distance/12);
		}
		
//		else{
//			pFinal = alineacion2[0];
//		}

		if( pFinal.distancia(sp.misJugadores()[0]) > 0.1 ){
			comandos.add(new ComandoIrA(0, pFinal));	
		}
		
	}
	
    //cada jugador se dirige a la posici�n de ataque
    private void _recoverAttackPosition(SituacionPartido sp) {      
    	Posicion [] al;
    	if(sp.balon().getY()>-10) al = alineacion1;
    	else al = alineacion2;
    	
    	for (int i = 0; i < 11; i++) {
    		comandos.add(new ComandoIrA(i, al[i]));
        }
    	
    }
    
    //cada jugador se dirige a la posici�n de defensa
    private void _recoverDefensivePosition(SituacionPartido sp) {  
    	Posicion [] al;
    	if(sp.balon().getY()>0) al = alineacion2;
    	else al = alineacion3;
    	
    	for (int i = 0; i < 11; i++) {
    		comandos.add(new ComandoIrA(i, al[i]));
        }
    }
    
    private void _markRivals(SituacionPartido sp){
    	int[] playersMarking = new int[11];
    	
    	for(int i = 0; i<11; ++i){
    		playersMarking[i] = -1;
    	}
    	    	
    	//Assign deffenders to the marking positions
    	for (int i = 1; i < 11; i++) {
    		int riv = sp.misJugadores()[i].indiceMasCercano(sp.rivales(),playersMarking);
    		Posicion markPos = sp.rivales()[riv].moverPosicion(Constantes.centroArcoInf.getX(), Constantes.centroArcoInf.getY(), 2);
    		double distance = sp.misJugadores()[i].distancia(markPos);   		
    		if( distance < 5  && markPos.getY()<0){
    			playersMarking[i] = riv;
    			comandos.add(new ComandoIrA(i, markPos));
    		}
        }

    }
    
    private int _ChaseTheBall(SituacionPartido sp) {   	
    	
    	//To avoid call _findIterationsToPoint twice with the same player
	   	int previousPlayer = -1;
	   	int previousIterations = 100;
	   	Posicion ballNextPos = _getBallPositionInNIterations(sp, 0);
	   	int player = ballNextPos.indiceMasCercano(sp.misJugadores());  	
	   	 boolean found = false;   
	   	 	   	 
	   	 for(int iterations = 0; iterations< 50; iterations+=2){
	   	 	Posicion p = _getBallPositionInNIterations(sp, iterations);
	   	 	
	   	 	player = p.indiceMasCercano(sp.misJugadores());
	   	 	int playerIterations = _findIterationsToPoint(sp,player,p);
	   	 	
	   	 	//At least, go near the ball position in the iteration
	   	 	if((player!=previousPlayer || playerIterations < previousIterations )
	   	 		&& playerIterations < iterations+3){
	   	 		comandos.add(new ComandoIrA(player, p));
	   	 		found = true;
	   	 	}   
	   	 	previousPlayer = player;
	   	 	previousIterations = playerIterations;
	   	 }   
	   	 if(!found){
	   	 	Posicion p = _getBallPositionInNIterations(sp, 25);
	   	 	player = p.indiceMasCercano(sp.misJugadores());
	   	 	comandos.add(new ComandoIrA(player, p));
	   	 }
	    	
		    	   	 
		 player = ballNextPos.indiceMasCercano(sp.misJugadores());
		 int rival = ballNextPos.indiceMasCercano(sp.rivales());
		 //THIS COULD BE MORE COMPLICATED, STUDYING THE ITERATONS TO THE BALL, ETC.
		 if(ballNextPos.distancia(sp.misJugadores()[player]) < ballNextPos.distancia(sp.rivales()[rival])){
			 comandos.add(new ComandoIrA(player, ballNextPos));
		 }
		 else if(sp.misJugadores()[player].getY() > sp.rivales()[rival].getY()){
			 boolean endFor = false;
			 int[] otherPlayers = ballNextPos.indicesMasCercanos(sp.misJugadores(), player);
			 for(int i = 0; i< otherPlayers.length && !endFor; ++i){
				 if(sp.misJugadores()[otherPlayers[i]].getY() < sp.rivales()[rival].getY()){
					 player = otherPlayers[i];
					 endFor = true;
				 }
			 }
			 if(sp.misJugadores()[player].distancia(ballNextPos)>1.8){
				 ballNextPos = ballNextPos.moverPosicion(Constantes.centroArcoInf.getX(), Constantes.centroArcoInf.getY(),2);
			 }
			 comandos.add(new ComandoIrA(player,ballNextPos));
		}
    	     	    	   	
    	return 0;
    }

    private int _findIterationsToPoint(SituacionPartido sp, int playerNum, Posicion point){
    	JugadorDetalle player = sp.detalleMisJugadores()[playerNum];
    	double playerSpeed = Constantes.getVelocidad(player.getVelocidad());
    	double meters = sp.misJugadores()[playerNum].distancia(point);

    	return (int)Math.ceil(meters/playerSpeed);
    }
    
    private Posicion _getBallPositionInNIterations(SituacionPartido sp, int iterations){
    	Posicion p = sp.balon();
    	
    	double speedX = p.getX() - previousBallPos.getX();
    	double speedY = p.getY() - previousBallPos.getY(); 	

    	double desaceleracion = FACTOR_DISMINUCION_VEL;     	
    	
    	double speed = previousBallPos.distancia(p) * desaceleracion;

    	//s = v*t + 1/2*a*t^2
    	double s = speed*iterations +1/(2*desaceleracion*iterations*iterations);
    	    	
    	p.moverPosicion(speedX * iterations, speedY * iterations,s);
    	
    	return p;    	
    }
    
    //Look for the best footballer to pass the ball to and make the pass
    private int _kickOffToAFreePlayer(SituacionPartido sp){
    	    	
        int kicker = sp.puedenRematar()[0];
        int catcher = -1;
        
        int[] cercanos = sp.misJugadores()[kicker].indicesMasCercanos(sp.misJugadores(),kicker);
        
        boolean pase = false;
        
         for (int j = 0; j < cercanos.length && !pase; j++) {
         	double distanciaEntreJugadores = sp.misJugadores()[kicker].distancia(sp.misJugadores()[cercanos[j]]);

        	double markedDistance = distanceMarked(sp,j);//sp.misJugadores()[cercanos[j]].distancia(sp.rivales()[cercanos[j]]);
         	
            if ( sp.misJugadores()[kicker].getY() < sp.misJugadores()[cercanos[j]].getY() 
            	&& distanciaEntreJugadores > 8) {
                //dar pase al jugador mas lejano que este en posicion mas ofensiva
            	            	
            	if(markedDistance > 3){ // El jugador no est� cubierto por ning�n rival
                	//_passBall(sp, kicker, cercanos[j]);
                    pase = true;
                    catcher = cercanos[j];          		
            	}
            }
        }
        
        _passBall(sp, kicker, catcher);        	          
            
    	return catcher;
    }
    
    double distanceMarked(SituacionPartido sp, int j){
    	Posicion playerPos = sp.misJugadores()[j];
    	int enem = playerPos.indiceMasCercano( sp.rivales() );
    	Posicion enemPos = sp.rivales()[enem];
    	return playerPos.distancia(enemPos);
    }
    
    
    //**��Merece la pena comprobar si hay un adversario en la l�nea de pase y busar otro pase mejor??**
    //Al realizar un pase a otro jugador, este debe saber que tiene que recibir el pase, 
    //y la la posici�n a la que se le manda
    private void _passBall(SituacionPartido sp, int lanzador, int receptor){

    	if(receptor < 0) receptor =  _calculateBestPlayerToMakePass(sp, lanzador);   		
    	
    	double distancia = sp.misJugadores()[lanzador].distancia(sp.misJugadores()[receptor]);
    	double vel = Constantes.getVelocidadRemate(detalle.getJugadores()[lanzador].getRemate()/(1.8 + distancia * 0.03));
    	double iteraciones = distancia / (vel);
    	
    	boolean alto = (iteraciones > 15 || sp.detalleMisJugadores()[lanzador].esPortero());
    	 	    	  	
    	//Calcular c�mo disminuye la velocidad hasta llegar al destino, para disparar m�s o menos fuerte
    	double desaceleracion = FACTOR_DISMINUCION_VEL;     	
    	
    	//Formula para calcular el espacio recorido 
    	//dependiendo de la velocidad, la aceleraci�n y el tiempo
    	//s = v*t + 1/2*a*t^2
    	double v = (distancia - 1/(2*desaceleracion*iteraciones*iteraciones))/iteraciones;
    
        comandos.add(new ComandoGolpearBalon(lanzador, sp.misJugadores()[receptor], v, alto));
        //comandos.add(new ComandoIrA(receptor, sp.misJugadores()[receptor])); 	
    }
    
    
    private int _calculateBestPlayerToMakePass(SituacionPartido sp, int kicker){
    	
    	Posicion kickerPlayer = sp.misJugadores()[kicker];
    	    	
    	int cercanos[] = kickerPlayer.indicesMasCercanos(sp.misJugadores(),kicker);
    	int receiver = cercanos[0];
    	double marked = distanceMarked(sp, receiver);
    
    	//From these players, look for the nearest to goal and find an unmarked position to make the pass
    	for(int i = 1; i< cercanos.length; ++i){
    		double distanceM = distanceMarked(sp, cercanos[i]);
    		if(distanceM > marked && sp.rivales()[cercanos[i]].getY() >= sp.rivales()[receiver].getY()){
    			receiver = cercanos[i];
    			marked = distanceM;
    		}    		
    	}
    	    	
    	return receiver; 
    }
    
        
    //Calcula una posici�n de desmarque m�s favorable para el jugador
    private void _getUnmarkedPosition(SituacionPartido sp, int jugador){
    	
    }
    
    
    //It's neede some player near the ball
    private void _dribblingAction(SituacionPartido sp){
    	
    	int playerNumber = sp.puedenRematar()[0];   	
        Posicion player = sp.misJugadores()[playerNumber];
        double scapeAngle = _getScapeAngle(sp, playerNumber);

        //Si no tiene rivales cerca, avanza con el bal�n        
        if( !_surroundProblems(sp,playerNumber) ){           //if( iterationsRival>=0 ){
        	//Continues running with the ball
        	Posicion pos = player.moverPosicion(0,3,3);
        	
        	if( scapeAngle > Math.PI/5 && scapeAngle < 4*Math.PI/5){
            	pos = pos.moverAngulo(Math.toDegrees(scapeAngle),2);
        	}
            	
        	comandos.add(new ComandoIrA(playerNumber, pos));
        	comandos.add(new ComandoGolpearBalon(playerNumber));//,Constantes.centroArcoSup, 0.35, false));            	           	
        }       
        else if( scapeAngle > Math.PI/5 && scapeAngle < 4*Math.PI/5){
        	comandos.add(new ComandoGolpearBalon(playerNumber,Math.toDegrees(scapeAngle),0.4,false));        	
        }	
        else if(player.distancia(Constantes.centroArcoSup)<33 && rand.nextBoolean()){
        	//comandos.add(new ComandoGolpearBalon(playerNumber,player.distancia(Constantes.centroArcoSup),1.0,30));
        	_shoot(sp,playerNumber);
        }
        else _kickOffToAFreePlayer(sp);
        
        if(sp.detalleMisJugadores()[playerNumber].esPortero()) _kickOffToAFreePlayer(sp);
        
        _tryToGoal(sp, playerNumber);
    }

	private boolean _surroundProblems(SituacionPartido sp, int player){
		boolean ret = false;
		Posicion playerPos = sp.misJugadores()[player];
		double pSpeed = sp.detalleMisJugadores()[player].getVelocidad();
    	int rivales[] = playerPos.indicesMasCercanos(sp.rivales());
    	int countSurroundingRivals = 0;
    	
    	for(int i = 0; i < rivales.length && !ret; ++i){
    		double distance = playerPos.distancia(sp.rivales()[rivales[i]]);
    		if( distance <= 9 ){
    			
    			if( sp.rivales()[rivales[i]].getY() > playerPos.getY() ) countSurroundingRivals++;
    			
    			double speed = sp.detalleJugadoresRivales()[i].getVelocidad();
    			if(speed >= pSpeed && sp.rivales()[rivales[i]].getY() > playerPos.getY()){
    				ret = true;
    			}
    			else if( distance < 2.2 && (speed >= pSpeed || playerPos.getY() < 0) ){
    				ret = true;
    			}
    		}
    	}
    	
    	if(countSurroundingRivals > 2) ret = true;
    	
		return ret;
	}

	private double _getScapeAngle(SituacionPartido sp, int playerNumber){
		Posicion playerPos = sp.misJugadores()[playerNumber];
    	int rivales[] = playerPos.indicesMasCercanos(sp.rivales());
    	double retAngle = 0;

    	boolean leaveFor = false;
    	for(int i = 0; i < (rivales.length /2) && !leaveFor; ++i){
    		Posicion rivalPos = sp.rivales()[rivales[i]];
    		double distance = playerPos.distancia(rivalPos);
    		if( distance < 8  && rivalPos.getY() > playerPos.getY() ){
    			retAngle = playerPos.angulo(rivalPos);
    			if(retAngle > Math.PI/2) retAngle -= Math.PI/4;
    			else retAngle += Math.PI/4;
    			leaveFor = true;    			
    		}    			
    	}
		
		return retAngle + Math.PI;
	}

	
    void _tryToGoal(SituacionPartido sp, int playerNumber){

    	Posicion player = sp.misJugadores()[playerNumber];
    	//Remate a porter�a
        Posicion a = Constantes.centroArcoSup;
        double ang = Math.abs(player.angulo(a) - Math.PI/2);
        //si el jugador que remata esta a menos de 30 metros del arco rival -> remata al arco
        
        if ( player.distancia(Constantes.centroArcoSup) < 35 && ang > 1.3 ) {
            //comandos.add(new ComandoGolpearBalon(playerNumber,Constantes.penalSup, 1.0, 30));
        	_passBall(sp, playerNumber, Constantes.penalSup.indiceMasCercano(sp.misJugadores(), playerNumber));           
        
        } else if (player.distancia(Constantes.centroArcoSup) < 20) {
        	_shoot(sp,playerNumber); 
        }
//        else if (player.distancia(Constantes.centroArcoSup) < 35 && ang > 1.2) {
//            comandos.add(new ComandoGolpearBalon(playerNumber,Constantes.penalSup, 0.8, 30));  
//        }
         
            	
    }
    
    private void _shoot ( SituacionPartido sp, int playerNumber){
    	//Posicion player = sp.misJugadores()[playerNumber];
    	Posicion goalKeeper = sp.misJugadores()[0];
    	//double angle = 0;
    	Posicion dest = new Posicion();
    	    	
    	if(goalKeeper.distancia(Constantes.posteDerArcoSup) > goalKeeper.distancia(Constantes.posteIzqArcoSup)){
    		//angle = player.angulo(Constantes.posteDerArcoSup) - Math.PI / 10;
    		double modif = Math.sin(Math.PI/10) * sp.balon().distancia(Constantes.posteDerArcoSup);
    		dest = Constantes.posteDerArcoSup.moverPosicion(-modif, 0);
    	}
    	else{
    		//angle = player.angulo(Constantes.posteIzqArcoSup) + Math.PI / 10;
    		double modif = Math.sin(Math.PI/10) * sp.balon().distancia(Constantes.posteIzqArcoSup);    		
    		dest = Constantes.posteIzqArcoSup.moverPosicion(modif, 0);
    	}
    	//double Zangle = _findShootAngle(sp, dest, playerNumber);
    	double distance = sp.balon().distancia(Constantes.centroArcoSup);
    	int angle = 0;
    	if(distance > 30) angle = 60;
    	else if(distance > 25) angle = 30;
    	else if (distance >18) angle = 20;
    	else angle = 10;
    	comandos.add(new ComandoGolpearBalon(playerNumber, dest, 1, angle));            	
    }
    
 /*   private double _findShootAngle(SituacionPartido sp, Posicion dest, int playerNumber){
    	double angle = 0;
    	double distancia = sp.balon().distancia(dest);
    	double vel = Constantes.getVelocidadRemate(detalle.getJugadores()[playerNumber].getRemate());
    	vel = Math.sin(vel);
    	double iteraciones = distancia / (vel);
    	
    	double desaceleracion = Constantes.G;  
    	double h = 1.5;
    	
    	//Formula para calcular el espacio recorido 
    	//dependiendo de la velocidad, la aceleraci�n y el tiempo
    	//s = v*t + 1/2*a*t^2
    	

    	double v = (h - 1/(2*desaceleracion*iteraciones*iteraciones))/iteraciones;
    	 	
    	angle = Math.toDegrees(Math.asin(v));
        //double balonDz = redondeaMultiplo(vel * Math.sin(angle), Constantes.G);
        
        return angle;
    }
   */ 
}